/// 音频流采集与发送服务
///
/// - 通过即构SDK音频数据观察器获取本地麦克风和远端用户音频流
/// - 将音频帧通过 WebSocket 发送到后端做 ASR + TTS
/// - 基于即构SDK 3.21.0版本官方API (参考官方demo实现)

import 'dart:typed_data';
import 'dart:math' as math;
import 'package:zego_express_engine/zego_express_engine.dart';
import 'dart:async';
import '../app_logger.dart';

/// 音频来源类型
enum AudioSide { local, remote }

/// 音频帧回调
typedef AudioFrameCallback = void Function(AudioSide side, Uint8List pcmData);

class AudioStreamService {
  static final AudioStreamService _instance = AudioStreamService._internal();
  factory AudioStreamService() => _instance;
  AudioStreamService._internal();

  AudioFrameCallback? _onAudioFrame;
  bool _isAudioDataObserverStart = false;
  bool _inited = false;

  // 音频帧计数器 (用于调试和日志控制)
  int _capturedTime = 0;
  int _playerTime = 0;

  // WebSocket 发送占位
  void Function(String side, Uint8List pcm)? sendFrameExternally;

  /// 初始化并开始音频数据观察
  Future<void> initialize({AudioFrameCallback? onAudioFrame}) async {
    if (_inited) return;

    _onAudioFrame = onAudioFrame;
    log.d('🎵 初始化音频流服务...');

    // 设置音频数据回调
    _setupAudioDataCallbacks();

    _inited = true;
    log.d('✅ 音频流服务初始化完成');
  }

  /// 设置音频数据回调 (参考官方demo)
  void _setupAudioDataCallbacks() {
    log.d('🔗 设置音频数据回调...');

    // 本地麦克风采集音频数据回调
    ZegoExpressEngine.onCapturedAudioData = (data, dataLength, param) {
      if (_isAudioDataObserverStart) {
        // 控制日志频率，避免刷屏
        if (_capturedTime > 1000 || _capturedTime == 0) {
          _capturedTime = 0;
          log.d('🎤 本地音频采集: dataLength=$dataLength, sampleRate=${param.sampleRate}, channel=${param.channel}');
        }
        _capturedTime += 1;

        _handleAudioFrame(AudioSide.local, data);
      }
    };

    // 远端用户音频处理回调 (正确的API)
    ZegoExpressEngine.onProcessRemoteAudioData = (data, dataLength, param, streamID, timestamp) {
      if (_isAudioDataObserverStart) {
        // 控制日志频率
        if (_playerTime > 1000 || _playerTime == 0) {
          _playerTime = 0;
          log.d('🔊 远端用户音频: dataLength=$dataLength, streamID=$streamID, sampleRate=${param.sampleRate}, channel=${param.channel}');
        }
        _playerTime += 1;

        _handleAudioFrame(AudioSide.remote, data);
      }
    };


    log.d('✅ 音频数据回调设置完成');
  }

  /// 开启音频数据观察器 (使用官方demo的正确调用方式)
  Future<void> startAudioDataObserver() async {
    if (_isAudioDataObserverStart) return;

    try {
      log.d('🔄 开始音频数据观察器...');

      // 按照官方demo的方式设置位掩码
      int observerBitMask = 0;
      observerBitMask |= ZegoAudioDataCallbackBitMask.Captured;  // 本地采集
      // onProcessRemoteAudioData 不需要位掩码设置，独立回调
      // observerBitMask |= ZegoAudioDataCallbackBitMask.Mixed;     // 混合音频 (可选)

      // 创建音频帧参数 (使用正确的构造函数)
      final param = ZegoAudioFrameParam(
        ZegoAudioSampleRate.SampleRate16K,  // 16kHz适合ASR
        ZegoAudioChannel.Mono               // 单声道适合ASR
      );

      // 调用正确的API (位置参数，不是命名参数)
      await ZegoExpressEngine.instance.startAudioDataObserver(
        observerBitMask,
        param
      );



      _isAudioDataObserverStart = true;
      log.d('✅ 音频数据观察器已启动 (位掩码: $observerBitMask)');
    } catch (e) {
      log.d('❌ 启动音频数据观察器失败: $e');
      rethrow;
    }
  }

  /// 停止音频数据观察器
  Future<void> stopAudioDataObserver() async {
    if (!_isAudioDataObserverStart) return;

    try {
      await ZegoExpressEngine.instance.stopAudioDataObserver();
      _isAudioDataObserverStart = false;

      // 重置计数器
      _capturedTime = 0;
      _playerTime = 0;

      log.d('🛑 音频数据观察器已停止');
    } catch (e) {
      log.d('❌ 停止音频数据观察器失败: $e');
    }
  }

  /// 处理音频帧数据
  void _handleAudioFrame(AudioSide side, Uint8List data) {
    if (!_isAudioDataObserverStart || data.isEmpty) return;

    // 回调给上层
    _onAudioFrame?.call(side, data);

    // 发送到后端
    _sendFrameToServer(side, data);
  }

  /// 发送音频帧到后端服务器
  void _sendFrameToServer(AudioSide side, Uint8List data) {
    // 检查音频数据是否有效（非静音）
    if (!_isAudioDataValid(data)) {
      return; // 跳过静音或音量过低的音频帧
    }

    // 如果外部提供发送实现，直接调用
    if (sendFrameExternally != null) {
      sendFrameExternally!(side == AudioSide.local ? 'local' : 'remote', data);
      return;
    }
  }

  /// 检查音频数据是否有效（非静音）
  bool _isAudioDataValid(Uint8List pcmData) {
    if (pcmData.isEmpty || pcmData.length < 64) {
      return false; // 数据太少，认为无效
    }

    // 计算音频能量（RMS）
    double sum = 0.0;
    int sampleCount = 0;

    // 采样检查，避免计算所有数据点
    for (int i = 0; i < pcmData.length && i < 1000; i += 2) {
      if (i + 1 < pcmData.length) {
        // 16位PCM数据，小端序
        int sample = (pcmData[i + 1] << 8) | pcmData[i];
        // 转换为有符号16位整数
        if (sample > 32767) sample -= 65536;
        sum += sample * sample;
        sampleCount++;
      }
    }

    if (sampleCount == 0) return false;

    // 计算RMS（均方根）
    double rms = math.sqrt(sum / sampleCount);

    // 设置阈值，低于此值认为是静音
    const double silenceThreshold = 10.0; // 可根据实际情况调整

    bool isValid = rms > silenceThreshold;

    // 偶尔打印调试信息（避免日志刷屏）
    if (_capturedTime % 1000 == 0) {
      log.d('🎵 音频有效性检查: RMS=$rms, threshold=$silenceThreshold, valid=$isValid');
    }

    return isValid;
  }

  /// 设置外部发送函数 (与WebSocket服务集成)
  void setExternalSender(void Function(String side, Uint8List pcm) sender) {
    sendFrameExternally = sender;
    log.d('🔗 外部音频发送器已设置');
  }

  /// 获取音频配置信息
  Map<String, dynamic> getAudioConfig() {
    return {
      'isObserving': _isAudioDataObserverStart,
      'inited': _inited,
      'mode': 'audio_data_observer',
      'description': '使用即构SDK音频数据观察器获取本地和远端用户音频流，包含静音过滤',
      'sampleRate': '16kHz',
      'channel': 'Mono',
      'silenceFilter': {
        'enabled': true,
        'threshold': 10.0,
        'description': '过滤静音或音量过低的音频帧，减少无效数据传输'
      },
      'apis': [
        'startAudioDataObserver',
        'onCapturedAudioData',
        'onProcessRemoteAudioData',
      ],
      'bitMask': {
        'captured': 'ZegoAudioDataCallbackBitMask.Captured',
        'note': 'onProcessRemoteAudioData不需要位掩码，独立回调',
      }
    };
  }

  /// 检查服务状态
  bool get isActive => _inited && _isAudioDataObserverStart;

  /// 获取统计信息
  Map<String, dynamic> getStats() {
    return {
      'initialized': _inited,
      'observing': _isAudioDataObserverStart,
      'hasCallback': _onAudioFrame != null,
      'hasExternalSender': sendFrameExternally != null,
      'frameCount': {
        'captured': _capturedTime,
        'player': _playerTime,
      }
    };
  }

  /// 清理音频数据回调
  void _clearAudioDataCallbacks() {
    ZegoExpressEngine.onCapturedAudioData = null;
    ZegoExpressEngine.onProcessRemoteAudioData = null;
    ZegoExpressEngine.onMixedAudioData = null;
    log.d('🧹 音频数据回调已清理');
  }

  /// 停止服务
  Future<void> dispose() async {
    log.d('🛑 停止音频流服务...');

    // 停止音频数据观察器
    await stopAudioDataObserver();

    // 清理回调
    _clearAudioDataCallbacks();

    _inited = false;
    _onAudioFrame = null;
    sendFrameExternally = null;

    log.d('✅ 音频流服务已停止');
  }

  // === 手动控制接口 ===

  /// 手动启动音频观察器 (供外部调用)
  Future<void> start() async {
    if (!_inited) {
      throw Exception('AudioStreamService not initialized');
    }
    await startAudioDataObserver();
  }

  /// 手动停止音频观察器 (供外部调用)
  Future<void> stop() async {
    await stopAudioDataObserver();
  }

  /// 切换音频观察器状态
  Future<void> toggle() async {
    if (_isAudioDataObserverStart) {
      await stop();
    } else {
      await start();
    }
  }
}